home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 6 / c_wndw.zip / DBFEDIT.C < prev    next >
Text File  |  1989-05-25  |  14KB  |  425 lines

  1. /*    (c) Marietta Systems, Inc  1987
  2.     All rights reserved */
  3. /*
  4. *    This program allows the viewing, amending, deleting and adding of
  5. *    records to a dBase II Plus '.dbf' file.
  6. *
  7. *    This program only works with files with less than 21 fields!
  8. */
  9. #include "mtest.h"
  10. #ifndef LATTICE
  11. #define memcpy memmove
  12. #endif
  13. /* */
  14. #define fileend (FN[fh].start + FN[fh].rec_len * FN[fh].prime)
  15. int  dbf_acpt(int, int, struct DBF_DEF*, enum ATTRIB);
  16. int  dbf_disp(int, int, struct DBF_DEF*, enum ATTRIB, int, int);
  17. int  dbf_init(int*, struct DBF_DEF**);
  18. void dbf_mnt(int, int, struct DBF_DEF*, long*);
  19. void do_search(int, char*, long*);
  20. void mnt_scrn(int, char*);
  21. void recblank(int);
  22. int  rec_acpt(int, int, struct DBF_DEF*);
  23. void rec_disp(int, int, struct DBF_DEF*);
  24. void show_nbr(int, long);
  25. int  stsearch(char*, char*);
  26. /*
  27. *
  28. *    Function to accept a dbase3 field
  29. *
  30. */
  31. int dbf_acpt(fh, field, format, atb)
  32. int fh, field;
  33. struct DBF_DEF *format;
  34. enum ATTRIB atb;{
  35.     int z, basept, ret, x = _CURSOR.X, y = _CURSOR.Y;
  36.     enum _JUST just;
  37.     char text[255];
  38.   /*  Error check */
  39.     if (fh < 5 || fh > MAXFILES || field < 0 
  40.         || field > FN[fh].start/32 - 2)
  41.         {disp_err("Parameter error in dbf_acpt", 1001); return -10;}
  42.   /*  Setup */
  43.     for (z = 0 , basept = 1 ; z < field ; basept += format[z++].dbf_len);
  44.     memcpy(text, &FN[fh].record[basept], format[field].dbf_len); 
  45.     text[format[field].dbf_len] = 0; /* copy to entry area */
  46.     switch ((int)format[field].dbf_type){
  47.         case 'C': just = left; break;
  48.         case 'L': just = left; break;
  49.         case 'N': just = decimal; break;
  50.         case 'D': just = date;
  51.             if (text[0] == 32) 
  52.                 {text[10] = -80; text[11] = text[12] = 0;}
  53.               else {text[12] = (char)atoi(&text[6]);  text[6] = 0;
  54.                 text[11] = (char)atoi(&text[4]);  text[4] = 0;
  55.                 text[10] = (char)(atoi(text) - 1980);}
  56.             memcpy (text, &text[10], 3);
  57.             break;
  58.         default: disp_err("Cannot edit memo field", 1002); 
  59.             return (INCHAR == ENTER ? 0 : 1);
  60.         }
  61.   /*  perform accept */
  62.     re_enter: ret = accept(text, just, atb, format[field].dbf_dig, 
  63.         format[field].dbf_dec);
  64.     if (ret < 0) return ret;  /* Pass through error code from accept */
  65.     if (ret && INCHAR == CTL_ENT) return ret;
  66.     switch ((int)format[field].dbf_type){
  67.         case 'C': break;
  68.         case 'L': text[0] = toupper(text[0]); 
  69.             if (text[0] != 'T' && text[0] != 'F')
  70.                 {disp_err("Logical field type requires 'T' or 'F'", 1);
  71.                 set_crsr(x,y); goto re_enter;}
  72.             display(text, x, y, ACC_DISP);
  73.             break;
  74.         case 'N': break;
  75.         case 'D': memcpy(&text[10], text, 3);
  76.             if (text[1] != 0) sprintf(text, "%4u%2u%2u", 
  77.                 1980 + text[10], (int)text[11], (int)text[12]);
  78.             else strcpy(text, "        ");
  79.         }
  80.     memcpy(&FN[fh].record[basept],text, format[field].dbf_len);
  81.     return ret;
  82.     }    /* end of function dbf_acpt */
  83. /*
  84. *
  85. *    Function to display a dbase3 field
  86. *
  87. */
  88. int dbf_disp(fh, field, format, atb , x, y)
  89. int fh, field, x, y;
  90. struct DBF_DEF *format;
  91. enum ATTRIB atb;{
  92.     int z, basept;
  93.     char text[255];
  94.   /*  Error check */
  95.     if (fh < 5 || fh > MAXFILES || field < 0 
  96.         || field > FN[fh].start/32 - 2)
  97.         {disp_err("Parameter error in dbf_disp", 1001); return -10;}
  98.   /*  Setup */
  99.     for (z = 0 , basept = 1 ; z < field ; basept += format[z++].dbf_len);
  100.     memcpy(text, &FN[fh].record[basept], format[field].dbf_len); 
  101.     text[format[field].dbf_len] = 0;
  102.     switch ((int)format[field].dbf_type){
  103.         case 'N': strcpy(&text[60], text);
  104.             justify(decimal, text, &text[60], format[field].dbf_dig,
  105.                 format[field].dbf_dec); 
  106.             break;
  107.         case 'D': if (text[0] == 32)  /* Null date */
  108.             {text[10] = -80; text[11] = text[12] = 0;}
  109.               else {text[12] = (char)atoi(&text[6]);  text[6] = 0;
  110.                 text[11] = (char)atoi(&text[4]);  text[4] = 0;
  111.                 text[10] = (char)(atoi(text) - 1980);}
  112.             date_out(text, &text[10]);
  113.             break;
  114.         default: break;
  115.         }
  116.   /*  perform display */
  117.     display(text, x, y, atb);
  118.     return 0;
  119.     }    /* end function dbf_disp */
  120. /*
  121. *
  122. *        Function to read in file and data dictionary
  123. *
  124. */
  125. int dbf_init(fields, format)
  126. int *fields;
  127. struct DBF_DEF **format;{
  128.     int fh, z;
  129.     char name[51], text[25];
  130.        for (z = 0; z < 8 ; KEYMATCH[z++] = 0); /* suppress function keys */
  131.     disp_err("",1); /* force display of function keys */
  132.   /* test if already initialized */
  133.     strcpy(name,"dbftest.dbf");
  134.   /* obtain file name  and setup format */
  135.     for (;;){
  136.         disp_msg("",0); 
  137.         display("Enter dBase 3+ file name  ", 20, 1, high);
  138.         if (accept(name, left, alt_reverse, 50, 0) < 0 || INCHAR == QUIT)
  139.             goodbye(0);
  140.         if ((fh = fileopen(name, dbase3, update)) < 0) continue;
  141.         if (!fh) {disp_err("File not found - try again", 1); continue;}
  142.         if (FN[fh].start < 65) 
  143.             {disp_err("Not valid dBase3+ file",1); idleloop(18);} 
  144.         if (FN[fh].fnext == NULL) 
  145.             disp_err("Could not load data dictionary",1);
  146.         if (FN[fh].start < 65 || FN[fh].fnext == NULL) 
  147.             {fileclos(fh); continue;} 
  148.         break;
  149.         } /* end for loop */
  150.     mk_wndw(5,15, 15,65, "Display of file header information");
  151.     display((byte*)FN[fh].fname, 1, 2, high);
  152.     sprintf(text, "prime  = %ld", FN[fh].prime); 
  153.     display(text, 2, 2, high);
  154.     sprintf(text, "start  = %d", FN[fh].start); 
  155.     display(text, 3, 2, high);
  156.     sprintf(text, "rec_len= %d", FN[fh].rec_len); 
  157.     display(text, 4, 2, high);
  158.     sprintf(text, "write  = %c", FN[fh].write); 
  159.     display(text, 5, 2, high);
  160.     sprintf(text, "ftype  = %d", (int)FN[fh].ftype); 
  161.     display(text, 6, 2, high);
  162.     if (FN[fh].fnext == NULL) 
  163.         display("NULL pointer value in fnext", 7, 2, high);
  164.         else display("Data dictionary loaded", 7, 2, high);
  165.     display("<< Press ESC key to continue >>", 9, 5, low);
  166.     while (grabchar() != ESC) disp_err("Press ESC key", 1);
  167.     rm_wndw();     
  168.     *fields = dbf_fld(fh);
  169.     *format = (struct DBF_DEF *)FN[fh].fnext;
  170.     return fh;
  171.     }    /* end function dbf_init */
  172. /*
  173. *
  174. *        Function to initialize the screen
  175. *
  176. */
  177. void mnt_scrn(fh, title)
  178. int fh;
  179. char *title;{  
  180.   /* setup function key map */
  181.     KEYMATCH[0] = 0X428; /* PgDn, Up arrow, Ctrl+Enter */
  182.     KEYMATCH[1] = 0X104; /* PgUp, Down arrow */
  183.     KEYMATCH[2] = KEYMATCH[3] = KEYMATCH[6] = KEYMATCH[5] = 0;
  184.     KEYMATCH[4] = 0XB400; /* F3, F5, F6, F8 */
  185.     KEYMATCH[7] = 0X4800;   /* Ctrl+PgDn, Ctrl+PgUp */
  186.     disp_err("",1); /* force display of new function keys */
  187.   /* Create info area at top of screen */
  188.     display("\030:Prev field     PgUp:Prev Record     Ctrl+PgUp:1st Record ",
  189.         1, 2, low);
  190.     display((byte*)FN[fh].fname, 1, 65, alt_low);
  191.     display("\031:Next field     PgDn:Next Record     Ctrl+PgDn:Last Record",
  192.         2, 2, low);
  193.   /* create edit window */
  194.     if (mk_wndw(TOP_LINE + 3, 1, SCRN_LEN, SCRN_WID, title) < 0) 
  195.         goodbye(10);
  196.     }  /* end function mnt_scrn */
  197. /*
  198. *
  199. *        Function to display a record on the screen 
  200. *
  201. */
  202. void rec_disp(fh, fields, format)
  203. int fh, fields;
  204. struct DBF_DEF *format;{
  205.     int x = 1, z, len;
  206.     clr_wndw();
  207.     if (FN[fh].record[0] != IN_USE) 
  208.         display("Record status is deleted", x++, 5, blink); 
  209.     for (z = 0 ; z < fields ; z++){
  210.         display(format[z].dbf_name, x, 1, high);
  211.         dbf_disp(fh, z, format, reverse, x, 12);
  212.         len = (format[z].dbf_type != 'N' ? format[z].dbf_len :
  213.             fld_len(decimal, format[z].dbf_dig, format[z].dbf_dec));
  214.         x += len / (SCRN_WID - 12) + 1;
  215.         }
  216.     }    /* end function rec_disp */
  217. /*
  218. *
  219. *        Function to accept a record on the screen 
  220. *
  221. */
  222. int rec_acpt(fh, fields, format)
  223. int fh, fields;
  224. struct DBF_DEF *format;{
  225.     int x = 1, z, len, kk;
  226.     if (FN[fh].record[0] != IN_USE) x++; 
  227.     for (z = 0 ; z < fields ; ){
  228.         set_crsr(x, 12);
  229.         if (dbf_acpt(fh, z, format, alt_reverse)) kk = INCHAR; else kk = 0;
  230.         switch (kk){
  231.         case 0: 
  232.             case ENTER: 
  233.             case CRS_DN: 
  234.             len = (format[z].dbf_type != 'N' ? format[z].dbf_len :
  235.                    fld_len(decimal, format[z].dbf_dig, format[z].dbf_dec));
  236.             x += len / (SCRN_WID - 12) + 1;
  237.             z++; break;
  238.         case CTL_ENT: 
  239.         case CRS_UP: if (z == 0) break;
  240.             len = (format[z-1].dbf_type != 'N' ? format[z-1].dbf_len :
  241.                     fld_len(decimal, format[z-1].dbf_dig,
  242.                     format[z-1].dbf_dec));
  243.             x -= len / (SCRN_WID - 12) + 1;
  244.             z--; break;
  245.         default: return kk;        
  246.         }
  247.         }
  248.     return 0;
  249.     }    /* end function rec_acpt */
  250. /*
  251. *
  252. *       Function to show current record location on screen
  253. *            (uses reserved functions 'set_clr' and 'scrn_map'
  254. */
  255. void show_nbr(fh, rec_nbr)
  256. int fh;
  257. long rec_nbr;{
  258.     char text[16];
  259.     set_clr(99, low); /* use error status color */
  260.     sprintf(text, "%5lu of %-5lu", rec_nbr, FN[fh].prime);
  261.     scrn_map(text, TOP_LINE + 2, 65); /* hairy technique */
  262.     set_clr(98, low); /* reset color */
  263.     }
  264. /*
  265. *
  266. *        Function to blank out a record
  267. *
  268. */
  269. void recblank(fh)
  270. int fh;{
  271.     memset(FN[fh].record, 32, FN[fh].rec_len); 
  272.     FN[fh].record[FN[fh].rec_len] = 0;
  273.     FN[fh].record[0] = IN_USE;
  274.     }
  275. /*
  276. *
  277. *    Find if string2 is in string1
  278. *
  279. */
  280. int stsearch(s1, s2)
  281. char *s1, *s2;{
  282.     int len2 = strlen(s2);
  283.     char *ptr;
  284.     ptr = strchr(s1, s2[0]);
  285.     while (ptr != NULL) {
  286.         if (!strncmp(ptr, s2, len2)) return 1;  /* found */
  287.         ptr = strchr(&ptr[1], s2[0]);
  288.         }
  289.     return 0;
  290.     }
  291. /*
  292. *
  293. *        Function to search for a specified string
  294. *
  295. */
  296. void do_search(fh, text, rec_nbr)
  297. char *text;
  298. int fh;
  299. long *rec_nbr;{
  300.     int count = 0;
  301.     long base = *rec_nbr;
  302.     char out[15];
  303.   /* setup */
  304.     if (mk_wndw(5,7, 11,73, "File search through dbase3+ file") < 0) 
  305.         return; 
  306.     display("Remember dates are stored as yyyymmdd ('19801231' for 12/31/80)",
  307.         5, 2, low);
  308.   /* obtain search text */
  309.     display("Enter search text ", 1, 1, high);
  310.     if (accept(text, left, alt_reverse, 16, 0)) 
  311.          {disp_err("Search abandoned",1); rm_wndw(); return;}
  312.     concat(text, 0); /* suppress trailing spaces */
  313.     strupr(text);
  314.   /* read around through the file */
  315.     for (;;) { 
  316.         if (!fileread(fh, nextrec, rec_nbr)) 
  317.         fileread(fh, firstrec, rec_nbr);
  318.         if (*rec_nbr == base) {disp_err("No matching text found", 1);
  319.         warble(500); idleloop(5); rm_wndw(); warble(0); return;}
  320.         if (5 == (count++)) { 
  321.             sprintf(out,"Record = %6lu", *rec_nbr);
  322.             display(out, 2, 5, reverse);
  323.             if (kbhit() && disp_qry("Do you wish to stop the search"))
  324.                 {rm_wndw(); return;}
  325.             count = 0;
  326.         }
  327.         strupr(&FN[fh].record[1]);
  328.         if (stsearch(&FN[fh].record[1], text))
  329.             {disp_err("Match found", 1); *rec_nbr -= 1L;
  330.             rm_wndw(); return;}
  331.          }
  332.     }                
  333. /*
  334. *
  335. *        Function to perform file maintenance
  336. *
  337. */
  338. void dbf_mnt(fh, fields, format, rec_nbr)
  339. int fh, fields;
  340. long *rec_nbr;
  341. struct DBF_DEF *format;{
  342.     int ret;
  343.     byte kk = 0;
  344.     char text[17];
  345.   /* setup */
  346.     mnt_scrn(fh, "Edit function for dBase3+ files");
  347.     if ((ret = fileread(fh, firstrec, rec_nbr)) < 0) goodbye(3);
  348.     show_nbr(fh, *rec_nbr - 1L);
  349.     text[0] = 0;
  350.     if (!ret) kk = INSERT;    /* Handle special case of empty file */
  351.   /* main accept loop */
  352.     for (;;){
  353.         if (!ret && !kk) recblank(fh);
  354.         if (!kk) {rec_disp(fh, fields, format); scrnsave(0);}
  355.         switch((kk ? kk : grabchar())){
  356.         case PGUP: 
  357.             case CTL_ENT: kk = 0; *rec_nbr -= 2L;
  358.                 if (*rec_nbr < 1L) 
  359.                     {*rec_nbr = 1L; disp_err("Top of file",1);} 
  360.                 break;
  361.         case PGDN: 
  362.             case ENTER: kk = 0; 
  363.                 if (*rec_nbr > FN[fh].prime) 
  364.                     {*rec_nbr = FN[fh].prime; disp_err("End of file", 1);}
  365.                 break;
  366.         case CTL_PGUP: *rec_nbr = 1L; kk = 0; break;
  367.         case CTL_PGDN: *rec_nbr = FN[fh].prime; kk = 0; break;
  368.         case UNDO: *rec_nbr -= 1L; 
  369.             if (FN[fh].record[0] != DELETED ||
  370.                     !disp_qry("Do you want to UNDO the delete")) 
  371.                     {kk = 0; break;}    
  372.                 FN[fh].record[0] = IN_USE;
  373.             if (filewrit(fh, rec_nbr) < 0) goodbye(6);
  374.             kk = 0; *rec_nbr -= 1L; break;
  375.         case SEARCH: do_search(fh, text, rec_nbr);
  376.                 kk = 0; break;
  377.         case INSERT: fileseek(fh, fileend); 
  378.                 *rec_nbr = FN[fh].prime + 1L;
  379.                 recblank(fh);
  380.              rec_disp(fh, fields, format);
  381.             kk = rec_acpt(fh, fields, format);
  382.             if (filewrit(fh, rec_nbr) < 0) goodbye(7);
  383.             if (!kk && *rec_nbr > FN[fh].prime) kk = INSERT;
  384.             break;
  385.         case DELETE: *rec_nbr -= 1L; kk = 0;
  386.                 if (!disp_qry("Do you really want to delete")) break;
  387.                 FN[fh].record[0] = DELETED;
  388.             if (filewrit(fh, rec_nbr) < 0) goodbye(8);
  389.             *rec_nbr -= 1L; break;
  390.         case AMEND: *rec_nbr -= 1L;
  391.                 if (FN[fh].record[0] != IN_USE) 
  392.                     {disp_err("You cannot amend a deleted record",1);
  393.                     kk = 0; break;}
  394.             kk = rec_acpt(fh, fields, format);
  395.             if (filewrit(fh, rec_nbr) < 0) goodbye(9);
  396.             break;
  397.         case QUIT: return;
  398.         case HELP: helpscrn(NULL); 
  399.         default: disp_msg("",0); *rec_nbr -= 1L; kk = 0; 
  400.                 warble(1000); idleloop(ERR_BEEP); warble(0);
  401.                 break;
  402.         } /* end switch */
  403.         if (kk && *rec_nbr) *rec_nbr -= 1L;
  404.         if ((ret = fileread(fh, relative, rec_nbr)) < 0) goodbye(5);
  405.         if (!ret) {disp_err("End of file reached",1);
  406.         ret = fileread(fh, lastrec, rec_nbr);}
  407.         show_nbr(fh, *rec_nbr - 1L);
  408.         } /* end for loop */
  409.     }    /* end of dbf_mnt function */
  410. /*
  411. *
  412. *        Main program 
  413. *
  414. */
  415. void main(){
  416. struct DBF_DEF *format;
  417. long rec_nbr = 1L;
  418. int fh, fields;
  419. clr_scrn("Test of dbf access");
  420. if ((fh = dbf_init(&fields, &format)) < 1)    goodbye(2);
  421. dbf_mnt(fh, fields, format, &rec_nbr);
  422. fileclos(fh); 
  423. goodbye(0);
  424. }
  425.